﻿using SoTaySinhVienUIT.Common;
using SoTaySinhVienUIT.Data;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Windows.ApplicationModel.Search;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Networking.BackgroundTransfer;
using Windows.Storage;
using Windows.UI.ApplicationSettings;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Grouped Items Page t template is documented at http://go.microsoft.com/fwlink/?LinkId=234231

namespace SoTaySinhVienUIT {
    /// <summary>
    /// A page that displays a grouped collection of items.
    /// </summary>
    public sealed partial class TopicGroupedPage : SoTaySinhVienUIT.Common.LayoutAwarePage {
        public TopicGroupedPage() {
            this.InitializeComponent();
        }

        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="navigationParameter">The parameter value passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
        /// </param>
        /// <param name="pageState">A dictionary of state preserved by this page during an earlier
        /// session.  This will be null the first time a page is visited.</param>
        protected override async void LoadState(Object navigationParameter, Dictionary<String, Object> pageState) {
           
            var loader = new Windows.ApplicationModel.Resources.ResourceLoader("MainPage");

            this.DefaultViewModel["HaveUpdate"] = false;
            SearchPane.GetForCurrentView().ShowOnKeyboardInput = true;
            await SampleDataSource.LoadData();

            // TODO: Assign a collection of bindable stsvs to this.DefaultViewModel["Groups"]
            var sampleDataGroups = SampleDataSource.GetGroups((String)navigationParameter);

            this.DefaultViewModel["Groups"] = sampleDataGroups;

            ////Populate Favorite group items
            var favoritetopicgroup = sampleDataGroups.Where(t => t.UniqueId.Equals("FAVORITE_GROUP")).ElementAt(0) as FavoriteTopicGroup;
            var favoriteitemgroup = sampleDataGroups.Where(t => t.UniqueId.Equals("FAVORITE_GROUP_ITEM")).ElementAt(0) as FavoriteItemGroup;
            var notegroup = sampleDataGroups.Where(t => t.UniqueId.Equals("FAVORITE_GROUP_ITEM_NOTE")).ElementAt(0) as FavoriteItemGroup;

            favoritetopicgroup.Items.Clear();
            favoriteitemgroup.Items.Clear();
            notegroup.Items.Clear();

            var collection = sampleDataGroups
                .Where(g => !g.UniqueId.Contains("FAVORITE"));

            //Favorite
            foreach (SampleDataTopic topic in collection.SelectMany(t => t.Items)) {

                if (topic.Favorite == true)
                    favoritetopicgroup.Items.Add(topic);

                if (!topic.Note.Equals(String.Empty))
                    notegroup.Items.Add(topic);
            }

            foreach (SampleDataItem item in collection.SelectMany(t => t.Items).SelectMany(i => (i as SampleDataTopic).Items)) {

                if (item.Favorite == true)
                    favoriteitemgroup.Items.Add(item);


                if (!item.Note.Equals(String.Empty))
                    notegroup.Items.Add(item);

            }


            if (favoritetopicgroup.Items.Count == 0) {

                var emptyTile = new SampleDataTopic("NOTHING_FAV",
                    loader.GetString("NothingFavTile"),
                    loader.GetString("NothingFavSub"),
                    "",
                    String.Empty,
                    String.Empty,
                    null);

                emptyTile.Icon = "\uE113";

                favoritetopicgroup.Items.Add(emptyTile);
            }

            if (favoriteitemgroup.Items.Count == 0) {

                var emptyTile = new SampleDataItem("NOTHING_FAV_ITEM",
                    loader.GetString("NothingFavTileItem"),
                    loader.GetString("NothingFavSubItem"),
                    "",
                    String.Empty,
                    String.Empty,
                    null, null);

                emptyTile.Icon = "\uE113";

                favoriteitemgroup.Items.Add(emptyTile);
            }

            if (notegroup.Items.Count == 0) {

                var emptyTile = new SampleDataItem("NOTHING_FAV_ITEM_NOTE",
                    loader.GetString("NothingFavTileItemNote"),
                    loader.GetString("NothingFavSubItemNote"),
                    "",
                    String.Empty,
                    String.Empty,
                    null, null);

                emptyTile.Icon = "\uE113";

                notegroup.Items.Add(emptyTile);
            }

            await SampleDataSource.SaveNoteLocal("note.txt");
            await SampleDataSource.SaveFavoriteLocal("fav.txt");

            ringUpdateContent.IsActive = true;

            bool noConnection = false;

            try {
                this.DefaultViewModel["HaveUpdate"] = await SampleDataSource.CheckUpdate();
            }
            catch (Exception exp) {
                noConnection = true;
            }
            if (noConnection) {
                LayoutAwarePage.ShowNoInternetDialog();
            }

            ringUpdateContent.IsActive = false;

            SettingsPane.GetForCurrentView().CommandsRequested += TopicGroupedPagePrivacy_CommandsRequested;
        }

        void TopicGroupedPagePrivacy_CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args) {
            SampleDataSource.AddSettingsCommands(args);
        }

        private void Header_Click(object sender, RoutedEventArgs e) {
                var group = (sender as FrameworkElement).DataContext;
                if (((SampleDataGroup)group).UniqueId.Contains("FAVORITE")) {
                    if (((SampleDataGroup)group).UniqueId.Contains("ITEM")) {
                        if (((FavoriteItemGroup)group).Items.Where(t => t.UniqueId.Contains("NOTHING")).Count() == 0) {
                            this.Frame.Navigate(typeof(SplitPage), ((FavoriteItemGroup)group).UniqueId);
                        }
                    }
                    else {
                        if (((FavoriteTopicGroup)group).Items.Where(t => t.UniqueId.Contains("NOTHING")).Count() == 0) {
                            this.Frame.Navigate(typeof(SplitPage), ((FavoriteTopicGroup)group).UniqueId);
                        }
                    }
                }
                else {
                    this.Frame.Navigate(typeof(SplitPage), ((SampleDataGroup)group).UniqueId);
                }
        }

        private async void ItemView_ItemClick(object sender, ItemClickEventArgs e) {

            var loader = new Windows.ApplicationModel.Resources.ResourceLoader("MainPage");

            var itemId = ((SampleDataItem)e.ClickedItem).UniqueId;

            if (itemId.Equals("NOTHING_FAV") || itemId.Equals("NOTHING_FAV_ITEM")) {

                var text = loader.GetString("NothingFav");

                var md_detail = new MessageDialog(text);

                await md_detail.ShowAsync();
            }
            else {
                if (itemId.Equals("NOTHING_FAV_ITEM_NOTE")) {

                    var text = loader.GetString("NothingFavItemNote");

                    var md_detail = new MessageDialog(text);

                    await md_detail.ShowAsync();

                }
                else {
                    if (((SampleDataItem)e.ClickedItem).Topic != null) { // Is DataItem
                        // Navigate to the appropriate destination page, configuring the new page
                        // by passing required information as a navigation parameter                    
                        var group = ((SampleDataItem)e.ClickedItem).Topic;

                        var dic = new Dictionary<String, String>(){
                            {"topic_id", ((SampleDataTopic)group).UniqueId},
                            {"item_id", itemId}
                        };

                        this.Frame.Navigate(typeof(SplitPage), dic);
                    }
                    else {
                        var topic = (SampleDataTopic)e.ClickedItem;

                        bool isNoted = topic.Note.Length > 0;
                        if (topic.Items.Count > 0) {
                            if (!isNoted) {
                                this.Frame.Navigate(typeof(ItemsPage), itemId);
                            }
                        }

                        if (topic.Items.Count == 0 || isNoted) {
                            var group = topic.Group;

                            var dic = new Dictionary<String, String>(){
                                {"group_id", ((SampleDataGroup)group).UniqueId},
                                {"item_id", topic.UniqueId}
                            };

                            this.Frame.Navigate(typeof(SplitPage), dic);
                        }
                    }
                }
            }
        }
        
        private async void btnUpdate_Click_1(object sender, RoutedEventArgs e) {

            var loader = new Windows.ApplicationModel.Resources.ResourceLoader("MainPage");

            if (!App._isUpdating) {

                App._isUpdating = true;

                bool noConnection = false;

                VisualStateManager.GoToState(btnUpdate, "Loading", false);

                bool isNewer = false;

                try {
                    isNewer = await SampleDataSource.UpdateFromWeb("local.txt");
                }
                catch (Exception exp) {
                    noConnection = true;
                }
                if (noConnection) {
                    LayoutAwarePage.ShowNoInternetDialog();
                }
                else {

                    if (isNewer) {

                        SampleDataSource.ClearGroups();
                        await SampleDataSource.LoadData();

                        // TODO: Assign a collection of bindable stsvs to this.DefaultViewModel["Groups"]
                        var sampleDataGroups = SampleDataSource.GetGroups("AllGroups");
                        this.DefaultViewModel["Groups"] = sampleDataGroups;

                        ////Populate Favorite group items
                        var favoritetopicgroup = sampleDataGroups.Where(t => t.UniqueId.Equals("FAVORITE_GROUP")).ElementAt(0) as FavoriteTopicGroup;
                        var favoriteitemgroup = sampleDataGroups.Where(t => t.UniqueId.Equals("FAVORITE_GROUP_ITEM")).ElementAt(0) as FavoriteItemGroup;
                        var notegroup = sampleDataGroups.Where(t => t.UniqueId.Equals("FAVORITE_GROUP_ITEM_NOTE")).ElementAt(0) as FavoriteItemGroup;

                        favoritetopicgroup.Items.Clear();
                        favoriteitemgroup.Items.Clear();
                        notegroup.Items.Clear();

                        var collection = sampleDataGroups
                            .Where(g => !g.UniqueId.Contains("FAVORITE"));

                        //Favorite
                        foreach (SampleDataTopic topic in collection.SelectMany(t => t.Items)) {

                            if (topic.Favorite == true)
                                favoritetopicgroup.Items.Add(topic);

                            if (!topic.Note.Equals(String.Empty))
                                notegroup.Items.Add(topic);
                        }

                        foreach (SampleDataItem item in collection.SelectMany(t => t.Items).SelectMany(i => (i as SampleDataTopic).Items)) {

                            if (item.Favorite == true)
                                favoriteitemgroup.Items.Add(item);


                            if (!item.Note.Equals(String.Empty))
                                notegroup.Items.Add(item);

                        }


                        if (favoritetopicgroup.Items.Count == 0) {

                            var emptyTile = new SampleDataTopic("NOTHING_FAV",
                                loader.GetString("NothingFavTile"),
                                loader.GetString("NothingFavSub"),
                                "",
                                String.Empty,
                                String.Empty,
                                null);

                            emptyTile.Icon = "\uE113";

                            favoritetopicgroup.Items.Add(emptyTile);
                        }

                        if (favoriteitemgroup.Items.Count == 0) {

                            var emptyTile = new SampleDataItem("NOTHING_FAV_ITEM",
                                loader.GetString("NothingFavTileItem"),
                                loader.GetString("NothingFavSubItem"),
                                "",
                                String.Empty,
                                String.Empty,
                                null, null);

                            emptyTile.Icon = "\uE113";

                            favoriteitemgroup.Items.Add(emptyTile);
                        }

                        if (notegroup.Items.Count == 0) {

                            var emptyTile = new SampleDataItem("NOTHING_FAV_ITEM_NOTE",
                                loader.GetString("NothingFavTileItem"),
                                loader.GetString("NothingFavSubItem"),
                                "",
                                String.Empty,
                                String.Empty,
                                null, null);

                            emptyTile.Icon = "\uE113";

                            notegroup.Items.Add(emptyTile);
                        }

                        // Download rtf

                        // Download zip
                        var folder = ApplicationData.Current.LocalFolder;
                        folder = await folder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);
                        folder = await folder.CreateFolderAsync("rtf", CreationCollisionOption.OpenIfExists);
                        folder = await folder.CreateFolderAsync("downloaded", CreationCollisionOption.OpenIfExists);

                        var source = new Uri("http://khabeouit.orgfree.com/data_uitstudenthandbook/rtf/update.zip");

                        var file = await folder.CreateFileAsync("update.zip", CreationCollisionOption.ReplaceExisting);

                        noConnection = false;

                        try {
                            BackgroundDownloader downloader = new BackgroundDownloader();
                            DownloadOperation download = downloader.CreateDownload(source, file);

                            await StartDownloadAsync(download);
                        }
                        catch (Exception exp) {
                            noConnection = true;
                        }
                        if (!noConnection) {

                            var destinationfolder = ApplicationData.Current.LocalFolder;
                            destinationfolder = await destinationfolder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);
                            destinationfolder = await destinationfolder.CreateFolderAsync("rtf", CreationCollisionOption.OpenIfExists);

                            // Decompress
                            using (var zipStream = await folder.OpenStreamForReadAsync("update.zip")) {
                                using (MemoryStream zipMemoryStream = new MemoryStream((int)zipStream.Length)) {
                                    await zipStream.CopyToAsync(zipMemoryStream);

                                    using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Read)) {
                                        foreach (ZipArchiveEntry entry in archive.Entries) {
                                            if (entry.Name != "") {
                                                using (Stream fileData = entry.Open()) {
                                                    StorageFile outputFile = await destinationfolder.CreateFileAsync(entry.Name, CreationCollisionOption.ReplaceExisting);
                                                    using (Stream outputFileStream = await outputFile.OpenStreamForWriteAsync()) {
                                                        await fileData.CopyToAsync(outputFileStream);
                                                        await outputFileStream.FlushAsync();
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                        }

                        var m = new MessageDialog(loader.GetString("UpdateCompleted") + SampleDataSource.Updated.ToString("d/M/yyyy hh:mm tt") + ")");
                        await m.ShowAsync();

                    }
                    else {
                        var ms = new MessageDialog(loader.GetString("NoUpdate") + SampleDataSource.Updated.ToString("d/M/yyyy hh:mm tt") + ")");
                        await ms.ShowAsync();
                    }

                    VisualStateManager.GoToState(btnUpdate, "UnLoading", false);

                    noConnection = false;

                    try {
                        this.DefaultViewModel["HaveUpdate"] = await SampleDataSource.CheckUpdate();
                    }
                    catch (Exception exp) {
                        noConnection = true;
                    }
                    if (noConnection) {
                        LayoutAwarePage.ShowNoInternetDialog();
                    }
                }

                App._isUpdating = false;
            }
        }

        private async Task StartDownloadAsync(DownloadOperation downloadOperation) {
            await downloadOperation.StartAsync().AsTask();
        }
    }
}
